#pragma once
#include <cstdint>

class source_location
{
public:
    static constexpr source_location current(
        const char* file = __builtin_FILE(),
        const char* func = __builtin_FUNCTION(),
        const uint_least32_t line = __builtin_LINE(),
#if defined (__APPLE__) || defined (_WIN32) || defined (_WIN64)
        const uint_least32_t colu = __builtin_COLUMN())
#else // gcc can't get column number
        const uint_least32_t colu = 0)
#endif
    noexcept
    {
        return source_location(file, func, line, colu);
    }

    source_location(const source_location&) = default;
    source_location(source_location&&) = default;

    constexpr const char* file_name() const noexcept { return _file; }
    constexpr const char* function_name() const noexcept { return _func; }

    constexpr uint_least32_t line() const noexcept { return _line; }
    constexpr uint_least32_t column() const noexcept { return _colu; }

private:
    constexpr source_location(const char* file, const char* func, const uint_least32_t line, const uint_least32_t colu) noexcept
        : _file(file), _func(func), _line(line), _colu(colu)
    {}

    const char* _file;
    const char* _func;
    const uint_least32_t _line;
    const uint_least32_t _colu;
};
